import Cesium, { AssociativeArray } from '../Ces/Cesium';

interface Destroyable {
  destroy(): void;
  update(frameState): void;
  id?: string;
}

class PrimitiveManager {
  private _objects: AssociativeArray

  constructor() {
    this._objects = new Cesium.AssociativeArray();
  }

  add(primitive: Destroyable, id?: string): any {
    if (!Cesium.defined(id)) {
      id = Cesium.createGuid();
    }
    primitive.id = id;

    if (this._objects.contains(id)) {
      throw new Cesium.RuntimeError(
        `An object with id ${id} already exists in this collection.`
      );
    }
    this._objects.set(id, primitive);

    return primitive;
  }

  getById(id: string): any {
    return this._objects.get(id);
  }

  removeAll(): void {
    for (let i = 0; i < this._objects.length; i++) {
      this._objects.values[i].destroy();
    }
    this._objects.removeAll();
  }

  remove(entity: Destroyable | string): boolean {
    if (!Cesium.defined(entity)) {
      return false;
    }

    const id = entity instanceof Object ? entity.id : entity;
    if (!id) return false;

    const obj = this.getById(id);
    if (!Cesium.defined(obj)) {
      return false;
    }

    if (!this._objects.remove(id)) {
      return false;
    }

    obj.destroy();
    return true;
  }

  destroy(): void {
    this.removeAll();
    Cesium.destroyObject(this);
  }

  isDestroyed(): boolean {
    return false;
  }

  update(frameState): void {
    for (let i = 0; i < this._objects.length; i++) {
      const p = this._objects.values[i];
      p.update(frameState);
    }
  }
}

export default PrimitiveManager;
